﻿Imports System.IO
Imports System.Threading
Imports System.Net

Public Class frmMain

    Private _Threads As New List(Of Thread)
    Private _tempListViewContainer As New List(Of ListViewItem)
    Private _FilterHandlerAdded As Boolean = False
    Private _DisplayNames As New Hashtable

    Private Sub OpenLogToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OpenLogToolStripMenuItem.Click

        Dim openFileDialog1 As New OpenFileDialog()
        openFileDialog1.InitialDirectory = My.Application.Info.DirectoryPath
        openFileDialog1.Title = "Open Skype Log"
        openFileDialog1.Filter = "Skype Log (*.log)|*.log"
        openFileDialog1.FilterIndex = 1
        openFileDialog1.RestoreDirectory = True

        If openFileDialog1.ShowDialog(Me) = DialogResult.OK Then

            If _FilterHandlerAdded Then
                RemoveHandler textSkypeIDFilter.TextChanged, AddressOf textSkypeIDFilter_TextChanged
                _FilterHandlerAdded = False
            End If

            If listviewSkypeUsers.Items.Count > 0 Then
                listviewSkypeUsers.Items.Clear()
                _tempListViewContainer.Clear()
            End If

            If _Threads.Count > 0 Then
                For Each thisThread As Thread In _Threads
                    thisThread.Abort()
                    Application.DoEvents()
                Next
                Do
                    For Each thisThread As Thread In _Threads
                        If Not thisThread.ThreadState = ThreadState.Running Then
                            _Threads.Remove(thisThread)
                            Exit For
                        End If
                        Application.DoEvents()
                    Next
                    If _Threads.Count = 0 Then Exit Do
                Loop
            End If

            Dim stFilePathAndName As String = openFileDialog1.FileName
            Dim MyFile As FileInfo = New FileInfo(stFilePathAndName)
            Dim stFileName As String = MyFile.Name
            Dim objFileStream As New FileStream(stFilePathAndName, FileMode.Open, FileAccess.Read, FileShare.Read)
            Dim objStreamReader As New StreamReader(objFileStream)

            Try

                While Not objStreamReader.EndOfStream

                    Dim thisLine As String = objStreamReader.ReadLine
                    If InStr(thisLine, "PresenceManager:") > 0 AndAlso InStr(thisLine, "noticing") > 0 Then

                        Dim lineParts() As String = Split(thisLine, Chr(30))
                        Dim skypeID As String = lineParts(2)
                        Dim skypeInfo As String = lineParts(3)

                        Dim rLoc As Integer = InStr(skypeInfo, "-r")
                        Dim lLoc As Integer = InStr(skypeInfo, "-l")

                        Dim externalIP As String = Split(Mid(skypeInfo, rLoc + 2, lLoc - (rLoc + 2)), ":")(0)
                        Dim internalIP As String = Split(Mid(skypeInfo, lLoc + 2, Len(skypeInfo) - (lLoc + 2)), ":")(0)
                        Dim matchFound As Boolean = False

                        Dim listItem As ListViewItem = New ListViewItem(skypeID)
                        listItem.SubItems.Add(externalIP)
                        listItem.SubItems.Add(internalIP)

                        If _tempListViewContainer.Count = 0 Then
                            _tempListViewContainer.Add(listItem)
                        Else
                            For Each item As ListViewItem In _tempListViewContainer
                                If item.Text = skypeID Then
                                    If externalIP = item.SubItems(1).Text AndAlso internalIP = item.SubItems(2).Text Then
                                        matchFound = True
                                    End If
                                End If
                            Next
                            If Not matchFound Then
                                _tempListViewContainer.Add(listItem)

                                Dim tStartData As New GeoIPLocator.GeoIPLocatorStartData
                                Dim tThread As New Thread(AddressOf GeoIPLocator.GetGeoIPData)

                                tStartData.IPAddress = externalIP
                                tStartData.MainForm = Me

                                _Threads.Add(tThread)
                                tThread.Start(tStartData)

                            End If
                        End If
                    End If

                End While

                textSkypeIDFilter.Text = ""
                If Not _FilterHandlerAdded Then
                    AddHandler textSkypeIDFilter.TextChanged, AddressOf textSkypeIDFilter_TextChanged
                    _FilterHandlerAdded = True
                End If
                textSkypeIDFilter_TextChanged(Me, Nothing)

                objStreamReader.Close()
                objFileStream.Close()

            Catch ex As Exception

                MessageBox.Show(ex.Message)

            Finally

                objStreamReader.Close()
                objFileStream.Close()

            End Try

        End If

    End Sub

    Public Sub AddGeoIPData(ByVal CSV As String)

        Dim IPAddress As String = Split(CSV, ",")(0)
        Dim Country As String = Split(CSV, ",")(2)
        Dim Locality As String = Split(CSV, ",")(4)
        Dim City As String = Split(CSV, ",")(5)

        For Each item As ListViewItem In _tempListViewContainer
            If item.SubItems(1).Text = IPAddress Then
                item.SubItems.Add(Country)
                item.SubItems.Add(Locality)
                item.SubItems.Add(City)
            End If
        Next

        textSkypeIDFilter_TextChanged(Me, Nothing)

    End Sub

    Private Sub textSkypeIDFilter_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs)
        listviewSkypeUsers.Items.Clear()
        If textSkypeIDFilter.Text = "" Then
            For Each item As ListViewItem In _tempListViewContainer
                listviewSkypeUsers.Items.Add(item)
            Next
        Else
            For Each item As ListViewItem In _tempListViewContainer
                If Not Len(item.Text) < Len(textSkypeIDFilter.Text) Then
                    If LCase(Mid(item.Text, 1, Len(textSkypeIDFilter.Text))) = LCase(textSkypeIDFilter.Text) Then
                        listviewSkypeUsers.Items.Add(item)
                    End If
                End If
            Next
        End If
    End Sub

    Private Sub ToolStripButton1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripButton1.Click
        OpenLogToolStripMenuItem_Click(Me, Nothing)
    End Sub

    Private Sub CloseToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CloseToolStripMenuItem.Click
        If _FilterHandlerAdded Then
            RemoveHandler textSkypeIDFilter.TextChanged, AddressOf textSkypeIDFilter_TextChanged
            _FilterHandlerAdded = False
        End If

        If listviewSkypeUsers.Items.Count > 0 Then
            listviewSkypeUsers.Items.Clear()
            _tempListViewContainer.Clear()
        End If
    End Sub


    Private Sub listviewSkypeUsers_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles listviewSkypeUsers.SelectedIndexChanged

    End Sub

    Private Sub ExitToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExitToolStripMenuItem.Click
        If _Threads.Count > 0 Then
            For Each thisThread As Thread In _Threads
                thisThread.Abort()
                Application.DoEvents()
            Next
            Do
                For Each thisThread As Thread In _Threads
                    If Not thisThread.ThreadState = ThreadState.Running Then
                        _Threads.Remove(thisThread)
                        Exit For
                    End If
                    Application.DoEvents()
                Next
                If _Threads.Count = 0 Then Exit Do
            Loop
        End If
        End
    End Sub

    Private Sub AboutToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AboutToolStripMenuItem.Click
        Dim tAbout As New AboutBox
        tAbout.ShowDialog(Me)
    End Sub

End Class

Friend Class GeoIPLocator

    Friend Class GeoIPLocatorStartData

        Friend IPAddress As String
        Friend MainForm As frmMain

    End Class

    Friend Shared Sub GetGeoIPData(ByVal StartData As GeoIPLocatorStartData)

        Dim GEOIP_CACHE_FILE As String = My.Application.Info.DirectoryPath & "\GeoIPCache.csv"
        Dim requestGeoIP As HttpWebRequest = Nothing
        Dim responseGeoIP As HttpWebResponse = Nothing
        Dim responseStreamReader As StreamReader = Nothing
        Dim responseCSV As String = ""
        Dim objFileStream As FileStream = Nothing
        Dim objStreamReader As StreamReader = Nothing

        Try

            If My.Computer.FileSystem.FileExists(GEOIP_CACHE_FILE) Then
                Try
                    objFileStream = New FileStream(GEOIP_CACHE_FILE, FileMode.Open, FileAccess.Read, FileShare.Read)
                    objStreamReader = New StreamReader(objFileStream)
                    While Not objStreamReader.EndOfStream
                        Dim thisLine As String = objStreamReader.ReadLine
                        Dim IPAddress As String = Split(thisLine, ",")(0)
                        If StartData.IPAddress = IPAddress Then
                            responseCSV = thisLine
                            Exit While
                        End If
                    End While
                    objStreamReader.Close()
                    objFileStream.Close()
                Catch ex As Exception

                Finally
                    objStreamReader.Close()
                    objFileStream.Close()
                End Try
            End If

            If responseCSV = "" Then

                requestGeoIP = HttpWebRequest.Create(String.Format("http://freegeoip.net/{0}/{1}", "csv", StartData.IPAddress))
                requestGeoIP.KeepAlive = False
                requestGeoIP.Method = "GET"

                responseGeoIP = requestGeoIP.GetResponse
                responseStreamReader = New StreamReader(responseGeoIP.GetResponseStream)
                responseCSV = responseStreamReader.ReadToEnd

                Dim objstreamWriter As StreamWriter = Nothing
                Try
                    objstreamWriter = New StreamWriter(GEOIP_CACHE_FILE, True)
                    objstreamWriter.Write(responseCSV)
                    objstreamWriter.Close()
                Catch ex As Exception

                Finally
                    objstreamWriter.Close()
                End Try

            End If

            StartData.MainForm.Invoke(Sub() frmMain.AddGeoIPData(responseCSV))

            StartData = Nothing

        Catch tex As ThreadAbortException

            Debug.WriteLine(tex.Message)

        Catch ex As Exception

        End Try

    End Sub

End Class
